package com.hongyi.system.controller;


import cn.dev33.satoken.secure.BCrypt;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.hongyi.common.framework.config.LycheeConfig;
import com.hongyi.common.framework.domain.JsonResult;
import com.hongyi.common.framework.domain.LoginUser;
import com.hongyi.common.framework.utils.bean.MapstructUtils;
import com.hongyi.common.framework.utils.file.FileUploadUtils;
import com.hongyi.common.framework.utils.string.StringUtils;
import com.hongyi.common.log.annotation.Log;
import com.hongyi.common.log.enums.BusinessType;
import com.hongyi.common.saToken.utils.LoginUtils;
import com.hongyi.common.web.controller.BaseController;
import com.hongyi.system.domain.dto.SysUserDto;
import com.hongyi.system.domain.dto.SysUserProfileDto;
import com.hongyi.system.domain.vo.ProfileVo;
import com.hongyi.system.domain.vo.SysUserVo;
import com.hongyi.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 个人信息 业务处理
 *
 * @author DingHao
 */
@ApiSort(value = 11)
@Api(tags = "个人信息控制器")
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController {

    @Autowired
    private ISysUserService userService;


    /**
     * 个人信息
     */
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "个人信息")
    @GetMapping
    public JsonResult<ProfileVo> profile(HttpServletRequest request) {
        SysUserVo user = userService.selectUserById(LoginUtils.getUserId());
        ProfileVo profileVo = new ProfileVo();
        profileVo.setUser(user);
        profileVo.setRoleGroup(userService.selectUserRoleGroup(user.getUserName()));
        profileVo.setPostGroup(userService.selectUserPostGroup(user.getUserName()));
        return JsonResult.ok(profileVo);
    }

    /**
     * 修改用户
     */
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "修改用户")
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public JsonResult<String> updateProfile(@Validated @RequestBody SysUserProfileDto sysUserProfileDto) {
        SysUserDto sysUserDto = MapstructUtils.convert(sysUserProfileDto, SysUserDto.class);
        String username = LoginUtils.getUserName();
        if (StringUtils.isNotEmpty(sysUserDto.getPhonenumber()) && !userService.checkPhoneUnique(sysUserDto)) {
            return JsonResult.fail("修改用户'" + username + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(sysUserDto.getEmail()) && !userService.checkEmailUnique(sysUserDto)) {
            return JsonResult.fail("修改用户'" + username + "'失败，邮箱账号已存在");
        }
        sysUserDto.setUserId(LoginUtils.getUserId());
        if (userService.updateUserProfile(sysUserDto) > 0) {
            return JsonResult.ok();
        }
        return JsonResult.fail("修改个人信息异常，请联系管理员");
    }

    /**
     * 修改密码
     */
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oldPassword", value = "旧密码", dataTypeClass = String.class, required = true),
            @ApiImplicitParam(name = "newPassword", value = "新密码", dataTypeClass = String.class, required = true)
    })
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/updatePwd")
    public JsonResult<String> updatePwd(String oldPassword, String newPassword) {
        SysUserVo user = userService.selectUserById(LoginUtils.getUserId());
        String password = user.getPassword();
        if (!BCrypt.checkpw(oldPassword, password)) {
            return JsonResult.fail("修改密码失败，旧密码错误");
        }
        if (BCrypt.checkpw(newPassword, password)) {
            return JsonResult.fail("新密码不能与旧密码相同");
        }

        if (userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(newPassword)) > 0) {
            return JsonResult.ok();
        }
        return JsonResult.fail("修改密码异常，请联系管理员");
    }

    /**
     * 头像上传
     */
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "头像上传")
    @ApiImplicitParam(name = "avatarfile", value = "用户头像文件", paramType = "query", dataTypeClass = MultipartFile.class, required = true)
    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/avatar")
    public JsonResult<String> avatar(@RequestPart("avatarfile") @RequestParam("avatarfile") MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            String avatar = FileUploadUtils.upload(LycheeConfig.getAvatarPath(), file);
            if (userService.updateUserAvatar(LoginUtils.getUserId(), avatar)) {
                // 更新缓存用户头像
                LoginUser loginUser = LoginUtils.getLoginUser();
                loginUser.setAvatar(avatar);
                LoginUtils.resetUser(loginUser);
                return JsonResult.ok("修改成功", avatar);
            }
        }
        return JsonResult.fail("上传图片异常，请联系管理员");
    }
}
